package org.shj.jvm;

/**
 * vm 参数：   -verbose:gc  -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 
 *          
 * 
 * 说明：
 * -Xmn 为新生代的内存大小
 * -XX:SurvivorRatio=8  新生代的Eden区与一个Survivor区的空间比是 8：1  
 * (新生代由一个Eden区和两个Survivor区组成, 新生代的总可用空间是 一个Eden区加上一个Survivor区的大小，此例为9M， 
 * 另一个Survivor区用于进行Minor GC 时，存放不能clear的对象)
 * 
 * 加入 -XX:PretenureSizeThreshold=3145728 (3MB) 这个参数后，大于3MB的对象将直接分配至老年代。但是
 * 此参数只对Serial和ParNew两款收集器有效。 去掉-XX:+UseSerialGC后，不管加不加-XX:PretenureSizeThreshold=3145728
 * 这个参数，a4均直接分配至老年代。
 * 
 * @author huangjian
 *
 */
public class TestAllocation {
	
	private static final int _1MB = 1024 * 1024;

	public static void main(String[] args){
		byte[] allocation1 = new byte[2 * _1MB]; //分配在Eden区
		byte[] allocation2 = new byte[2 * _1MB]; //分配在Eden区
		byte[] allocation3 = new byte[2 * _1MB]; //分配在Eden区
		
		System.out.println(allocation1);
		
		//上面三个对象分配完毕后，新生代剩余 9 - 2 - 2 -2 = 3，不足以存放 allocation4，此时会先进行一次Minor GC，
		//但是allocation1， allocation2， allocation3 均为不可clear对象，然而另一个Survivor区只有1M，又无法放入，
		//垃圾回收器会把此三个对象放入老年代。
		//(上述是书上的描述，用JDK8运行此程序时，三个2M 的对象并没有放到老年代中，而是直接把 allocation4 分配到了老年代中, 需
		//   去掉 XX:PretenureSizeThreshold 这个参数)
		byte[] allocation4 = new byte[4 * _1MB];
		
		System.out.println(allocation1);
	}
}
